﻿using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Vision.ModuleTool;
using Vision.VControl;
using Vision.VHelper;



namespace Vision
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private bool isMoving = false;
        private Point startPoint;
        private Point controlStartPoint;
        private DrawState drawState = DrawState.Normal;
        private FlowNode node1;
        private FlowNode node2;
        private int nodeNo = 0;
        private Path selectedLine = null;
        private FlowNode selectedFlowNode = null;

        public ObservableCollection<string> ImgHandleLabels { get; set; }
        public ObservableCollection<string> ModelLabels { get; set; }
        private List<ConnectionHelper> connectionsList = new List<ConnectionHelper>();

        public FlowControlTool FlowControl = new FlowControlTool();


        public MainWindow()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // 窗体初始化加载完成执行逻辑
            Pl_ImgHandle.Visibility = Visibility.Collapsed;
            Pl_Model.Visibility = Visibility.Collapsed;

            // 确保 ItemsControl 的集合在设置 ItemsSource 之前是空的
            ImgHandleLabels = new ObservableCollection<string>
            {
                "加载图像",
                "灰度化图像",
                "二值化图像",
                "形态学处理"
            };
            ModelLabels = new ObservableCollection<string>
            {
                "圆查找",
                "绘制圆形ROI",
                "创建模板",
                "模板匹配"
            };
            DataContext = this;
        }

        private void Btn_ImgHandle_Click(object sender, RoutedEventArgs e)
        {
            // 判断当前的可见性状态并切换
            Pl_ImgHandle.Visibility = Pl_ImgHandle.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
        }

        private void Btn_Model_Click(object sender, RoutedEventArgs e)
        {
            // 判断当前的可见性状态并切换
            Pl_Model.Visibility = Pl_Model.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
        }

        private void 单次执行ToolStripMenuItem_Click(object sender, RoutedEventArgs e)
        {

        }


        #region 模块拖拽并初始化

        /// <summary>
        /// 模块拖拽至流程面板中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Pl_FlowProcess_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("Label"))
            {
                e.Effects = DragDropEffects.Copy | DragDropEffects.Move;
            }
            else
            {
                e.Effects = DragDropEffects.None;
            }
        }

        /// <summary>
        /// 模块拖拽至流程面板并释放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Pl_FlowProcess_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("Label"))
            {
                Label lbl = e.Data.GetData("Label") as Label;
                if (lbl != null)
                {
                    // 在Canvas中添加FlowNode控件,创建自定义流程控件对象
                    int flowNumber = GetFlowNumber();
                    string labelContent = lbl.Content.ToString();
                    string flowName = $"{flowNumber}:{labelContent}";
                    string flowType = labelContent; // 假设 lbl.Content 已经是一个合适的类型名称
                    Vision.VControl.FlowNode flowNode = new Vision.VControl.FlowNode(flowType, flowName);

                    // 设置控件的位置
                    Canvas.SetLeft(flowNode, e.GetPosition(Pl_FlowProcess).X);
                    Canvas.SetTop(flowNode, e.GetPosition(Pl_FlowProcess).Y);
                    // 设置流程节点的文本
                    flowNode.MouseDown += NodeMouseDown;
                    flowNode.MouseMove += NodeMouseMove;
                    flowNode.MouseUp += NodeMouseUP;

                    // 注册 NodeClick 事件
                    flowNode.MouseLeftButtonDown += NodeClick;

                    // 添加右键点击事件
                    flowNode.MouseRightButtonDown += FlowNode_MouseRightButtonDown;

                    // 把流程节点添加到对应的容器
                    Pl_FlowProcess.Children.Add(flowNode);
                }
            }
        }

        private List<int> listnum = new List<int>();
        private int GetFlowNumber()
        {
            int num = 1;
            while (true)
            {
                if (listnum.Contains(num))
                {
                    num++;
                }
                else
                {
                    listnum.Add(num);
                    return num;
                }
            }
        }

        /// <summary>
        /// 在流程节点上按下鼠标左键处理事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NodeMouseDown(object sender, MouseButtonEventArgs e)
        {
            // 判断鼠标是否是左键按下
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                isMoving = true;
                var control = sender as UIElement;
                // 获取鼠标初始位置
                startPoint = e.GetPosition(Pl_FlowProcess);
                if (control != null)
                {
                    // 获取控件初始位置
                    controlStartPoint = new Point(Canvas.GetLeft(control), Canvas.GetTop(control));
                }
                Mouse.Capture(control); // 捕获鼠标输入
            }
        }

        /// <summary>
        /// 鼠标按下在流程面板移动过程进行的设置操作事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NodeMouseMove(object sender, MouseEventArgs e)
        {
            // 判断是否是移动状态，并且左键一直按下
            if (isMoving && e.LeftButton == MouseButtonState.Pressed)
            {
                var control = sender as FlowNode;
                if (control != null)
                {
                    var parent = VisualTreeHelper.GetParent(control) as Canvas;
                    if (parent != null)
                    {
                        // 计算位移量
                        var currentPoint = e.GetPosition(Pl_FlowProcess);
                        double offsetX = currentPoint.X - startPoint.X;
                        double offsetY = currentPoint.Y - startPoint.Y;

                        // 计算控件的新位置
                        double newLeft = controlStartPoint.X + offsetX;
                        double newTop = controlStartPoint.Y + offsetY;

                        // 获取控件本身的宽和高
                        double width = control.RenderSize.Width;
                        double height = control.RenderSize.Height;
                        // 动态获取流程编辑区域的大小
                        double parentWidth = parent.ActualWidth;
                        double parentHeight = parent.ActualHeight;
                        // 判断拖拽的过程中不能超出边界
                        newLeft = newLeft < 0 ? 0 : (newLeft + width > parentWidth) ? parentWidth - width : newLeft;
                        newTop = newTop < 0 ? 0 : (newTop + height > parentHeight) ? parentHeight - height : newTop;
                        // 设置控件新偏移量
                        Canvas.SetLeft(control, newLeft);
                        Canvas.SetTop(control, newTop);
                    }
                    UpdateConnectionsForNode(control);
                }
            }
        }

        /// <summary>
        /// 在流程节点上松开鼠标左键处理事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NodeMouseUP(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Released)
            {
                isMoving = false;
                var control = sender as UIElement;
                if (control != null)
                {
                    Mouse.Capture(null); // 释放鼠标捕获
                }
            }
        }

        /// <summary>
        /// 单击流程节点左键事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NodeClick(object sender, MouseButtonEventArgs e)
        {
            var control = sender as FlowNode;
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                if (drawState == DrawState.DrawLine)
                {
                    if (nodeNo == 0)
                    {
                        if (control != null)
                        {
                            node1 = control as FlowNode;
                            nodeNo = 1;
                        }
                        else
                        {
                            MessageBox.Show("请选择一个流程节点");
                        }
                    }
                    else if (nodeNo == 1)
                    {
                        if (control != null)
                        {
                            node2 = control as FlowNode;
                            if (node1 != node2)
                            {
                                node1.NextNodes.Add(node2.NodeID);
                                node2.PreviousNodes.Add(node1.NodeID);
                                nodeNo = 0;
                                AddConnection(node1, node2);

                                drawState = DrawState.Normal;
                            }
                        }
                        else
                        {
                            MessageBox.Show("请选择需要连线目标节点");
                        }
                    }
                }
                else if (drawState == DrawState.Normal)
                {

                }
            }
        }

        // 右键点击事件的处理方法
        private void FlowNode_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            selectedFlowNode = sender as Vision.VControl.FlowNode;
            if (selectedFlowNode != null)
            {
                // 显示右键菜单
                var contextMenu = (ContextMenu)FindResource("FlowNodeContextMenu");
                contextMenu.IsOpen = true;
                e.Handled = true;
            }
        }

        #endregion

        #region 流程面板连线

        /// <summary>
        /// 流程面板右击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Pl_FlowProcess_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            // 在画布上右键点击时显示上下文菜单
            var contextMenu = (ContextMenu)FindResource("NodeContextMenu");
            contextMenu.IsOpen = true;

        }

        /// <summary>
        /// 点击连线
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ConnectMenuItem_Click(object sender, RoutedEventArgs e)
        {
            drawState = DrawState.DrawLine;
        }

        public void AddConnection(FlowNode startNode, FlowNode endNode)
        {
            var connection = new ConnectionHelper(startNode, endNode, Pl_FlowProcess);
            connectionsList.Add(connection);
            // 可以在这里调用UpdatePath来初始化PathElement
        }

        public void RemoveConnection(Path line)
        {
            for (int i = connectionsList.Count - 1; i >= 0; i--)
            {
                var connection = connectionsList[i];
                if (connection.PathElement == line)
                {
                    connectionsList.Remove(connection);
                    Pl_FlowProcess.Children.Remove(connection.PathElement);
                    if (connection.StartNode != null && connection.EndNode != null)
                    {
                        if (connection.StartNode.NextNodes.Contains(connection.EndNode.NodeID))
                        {
                            connection.StartNode.NextNodes.Remove(connection.EndNode.NodeID);
                        }
                        if (connection.EndNode.PreviousNodes.Contains(connection.StartNode.NodeID))
                        {
                            connection.EndNode.PreviousNodes.Remove(connection.StartNode.NodeID);
                        }
                    }
                }
            }
        }

        private void UpdateConnectionsForNode(FlowNode node)
        {
            foreach (var connection in connectionsList.Where(c => c.StartNode == node || c.EndNode == node))
            {
                connection.DrawPointToPointLine();
            }
        }

        #endregion

        private void Pl_FlowProcess_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var hitTestResult = VisualTreeHelper.HitTest(Pl_FlowProcess, e.GetPosition(Pl_FlowProcess));
            if (hitTestResult != null && hitTestResult.VisualHit is Path path)
            {
                if (selectedLine != null)
                {
                    selectedLine.Stroke = Brushes.DarkRed;
                }
                selectedLine = path;
                selectedLine.Stroke = Brushes.Red;

                // 显示右键菜单
                var contextMenu = FindResource("LineContextMenu") as ContextMenu;
                if (contextMenu != null)
                {
                    contextMenu.PlacementTarget = path;
                    contextMenu.IsOpen = true;
                }
            }
        }

        private void DeleteLineMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (selectedLine != null)
            {
                Pl_FlowProcess.Children.Remove(selectedLine);
                RemoveConnection(selectedLine);
                selectedLine = null;
            }
        }

        private void DeleteFlowNodeMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (selectedFlowNode != null)
            {
                // 这里添加删除逻辑
                // 例如，从Pl_FlowProcess.Children中移除flowNode
                Pl_FlowProcess.Children.Remove(selectedFlowNode);
            }
        }
    }
}